package top.lishuoboy.redis.controller;

import cn.hutool.core.date.TimeInterval;
import cn.hutool.http.HttpUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/** 模拟高并发测试 redis 分布式锁 */
@Slf4j
public class LockThreadClient {
    private static int count = 100;

    @SneakyThrows
    public static void main(String[] args) {
        TimeInterval timer = new TimeInterval();
        Jedis jedis = new Jedis();
        jedis.flushDB();

        ExecutorService pool = Executors.newFixedThreadPool(1000);
        timer.start();
        for (int i = 1; i <= count; i++) {
//            pool.submit(new LockThread("NoLock"));
//            pool.submit(new LockThread("Lock"));
            pool.submit(new LockThread("RLock1"));
            pool.submit(new LockThread("RLock2"));
        }

        pool.shutdown();

        //等待所有线程执行完成
        while (true) {
            if (pool.isTerminated()) {
                break;
            }
            TimeUnit.SECONDS.sleep(1);
        }

        String numNoLock = jedis.get("numNoLock");
        String numLock = jedis.get("numLock");
        log.debug("最终值，numNoLock=={}, numLock=={}", numNoLock, numLock);
        String numRLock1 = jedis.get("numRLock1");
        String numRLock2 = jedis.get("numRLock2");
        log.debug("最终值，timer=={}, numRLock1=={}, numRLock2=={}", timer.intervalSecond(), numRLock1, numRLock2);
    }
}

@Slf4j
@AllArgsConstructor
class LockThread implements Runnable {
    private String type;

    @Override
    public void run() {
        if ("NoLock".equals(type)) {
            HttpUtil.get("http://localhost:8080/testNoLock/");
        } else if ("Lock".equals(type)) {
            HttpUtil.get("http://localhost:8080/testLock/");
        } else if ("RLock1".equals(type)) {
            HttpUtil.get("http://localhost:8080/testRedissonRLock1");
        } else if ("RLock2".equals(type)) {
            HttpUtil.get("http://localhost:8080/testRedissonRLock2");
        } else {
            log.warn("未知type=={}", type);
        }
    }
}